home *** CD-ROM | disk | FTP | other *** search
- /*
- Half-Life MAP viewing utility.
- Copyright (C) 2003 Ryan Samuel Gregg
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- #include "stdafx.h"
- #include "Engine.h"
-
- CEngine::CEngine(CConfig *Config, CRichTextBox *txtConsole)
- {
- this->Config = Config;
- this->txtConsole = txtConsole;
-
- vMouseOld.X = 0;
- vMouseOld.Y = 0;
- vMouseNew.X = 0;
- vMouseNew.Y = 0;
-
- Frustum = new CFrustum();
- Camera = new CCamera();
- TextureManager = NULL;
- World = NULL;
- HighlightObject = NULL;
- PointFile = NULL;
- }
-
- bool CEngine::Initialize(HWND hWND)
- {
- this->hWND = hWND;
-
- int iPixelFormat;
- PIXELFORMATDESCRIPTOR pfd;
-
- pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = Config->bColorBits;
- pfd.cRedBits = 0;
- pfd.cRedShift = 0;
- pfd.cGreenBits = 0;
- pfd.cGreenShift = 0;
- pfd.cBlueBits = 0;
- pfd.cBlueShift = 0;
- pfd.cAlphaBits = 0;
- pfd.cAlphaShift = 0;
- pfd.cAccumBits = 0;
- pfd.cAccumRedBits = 0;
- pfd.cAccumGreenBits = 0;
- pfd.cAccumBlueBits = 0;
- pfd.cAccumAlphaBits = 0;
- pfd.cDepthBits = Config->bDepthBits;
- pfd.cStencilBits = 0;
- pfd.cAuxBuffers = 0;
- pfd.iLayerType = PFD_MAIN_PLANE;
- pfd.bReserved = 0;
- pfd.dwLayerMask =0;
- pfd.dwVisibleMask = 0;
- pfd.dwDamageMask = 0;
-
- hDC = GetDC(hWND);
-
- if((iPixelFormat = ChoosePixelFormat(hDC, &pfd)) == 0)
- return false;
-
- if(SetPixelFormat(hDC, iPixelFormat, &pfd) == false)
- return false;
-
- if((hGLRC = wglCreateContext(hDC)) == 0)
- return false;
-
- if(wglMakeCurrent(hDC, hGLRC) == false)
- return false;
-
- glClearColor(Config->cBackColor.R, Config->cBackColor.G, Config->cBackColor.B, Config->cBackColor.A);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- glHint(GL_FOG_HINT, GL_NICEST);
- glCullFace(GL_FRONT);
- glShadeModel(GL_FLAT);
-
- // Lighting
- float fGlobalAmbient[] = { 0.25f, 0.25f, 0.25f, 1.0f };
- float fLightAmbient0[] = { 0.5f, 0.5f, 0.5f, 1.0f };
- float fLightDiffuse0[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- float fLightSpecular0[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- float fLightPosition0[] = { 4096.0f, 4096.0f, 4096.0f, 0.0f };
- float fMaterialSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- float fMaterialEmission[] = { 0.0f, 0.0f, 0.0f, 1.0f };
-
- //glLightModelfv(GL_AMBIENT, fGlobalAmbient);
-
- glLightfv(GL_LIGHT0, GL_AMBIENT, fLightAmbient0);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, fLightDiffuse0);
- glLightfv(GL_LIGHT0, GL_SPECULAR, fLightSpecular0);
- glLightfv(GL_LIGHT0, GL_POSITION, fLightPosition0);
-
- float fLightAmbient1[] = { 0.25f, 0.25f, 0.25f, 1.0f };
- float fLightDiffuse1[] = { 0.5f, 0.5f, 0.5f, 1.0f };
- float fLightSpecular1[] = { 0.5f, 0.5f, 0.5f, 1.0f };
- float fLightPosition1[] = { -4096.0f, -4096.0f, -4096.0f, 0.0f };
-
- glLightfv(GL_LIGHT1, GL_AMBIENT, fLightAmbient1);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, fLightDiffuse1);
- glLightfv(GL_LIGHT1, GL_SPECULAR, fLightSpecular1);
- glLightfv(GL_LIGHT1, GL_POSITION, fLightPosition1);
-
- glMaterialfv(GL_BACK, GL_SPECULAR, fMaterialSpecular);
- glMaterialfv(GL_BACK, GL_EMISSION, fMaterialEmission);
-
- // Fog
- switch(Config->eFogMode)
- {
- case FogMode::Exp:
- glFogi(GL_FOG_MODE, GL_EXP);
- break;
- case FogMode::Exp2:
- glFogi(GL_FOG_MODE, GL_EXP2);
- break;
- case FogMode::Linear:
- default:
- glFogi(GL_FOG_MODE, GL_LINEAR);
- break;
- }
-
- float fFogColor[] = { Config->cFogColor.R, Config->cFogColor.G, Config->cFogColor.B, Config->cFogColor.A };
-
- glFogfv(GL_FOG_COLOR, (float*)&fFogColor);
- glFogf(GL_FOG_DENSITY, Config->fFogDensity);
- glFogf(GL_FOG_START, Config->fFogStart);
- glFogf(GL_FOG_END, Config->fFogEnd);
-
- BuildFont(S"Courier New");
-
- wglMakeCurrent(0, 0);
-
- return true;
- }
-
- void CEngine::Destroy()
- {
- MakeCurrent();
- DestroyFont();
- MakeNotCurrent();
-
- DestroyTextures();
-
- ReleaseDC(hWND, hDC);
- wglDeleteContext(hGLRC);
- }
-
- void CEngine::MakeCurrent()
- {
- wglMakeCurrent(hDC, hGLRC);
- }
-
- void CEngine::MakeNotCurrent()
- {
- wglMakeCurrent(0, 0);
- }
-
- void CEngine::BuildFont(String *FontName)
- {
- HFONT Font;
- HFONT OldFont;
-
- void *pFontName = System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(FontName).ToPointer();
-
- iFontBase = glGenLists(96);
- Font = CreateFont(-12, // Height
- 0, // Width
- 0, // Angle
- 0, // Escape angle
- FW_BOLD, // Font weight
- false, // Italic
- false, // Underline
- false, // Strikeout
- ANSI_CHARSET, // Character Set Identifier
- OUT_TT_PRECIS, // Output Precision
- CLIP_DEFAULT_PRECIS, // Clipping Precision
- ANTIALIASED_QUALITY, // Output Quality
- FF_DONTCARE | DEFAULT_PITCH, // Family And Pitch
- (LPCSTR)pFontName); // Font Name
-
- OldFont = (HFONT)SelectObject(hDC, Font);
- wglUseFontBitmaps(hDC, 32, 96, iFontBase);
- SelectObject(hDC, OldFont);
- DeleteObject(Font);
-
- System::Runtime::InteropServices::Marshal::FreeHGlobal((IntPtr(pFontName)));
- }
-
- void CEngine::DestroyFont()
- {
- glDeleteLists(iFontBase, 96);
- }
-
- void CEngine::Resize(int iWidth, int iHeight)
- {
- if(iWidth == 0 || iHeight == 0)
- return;
-
- MakeCurrent();
-
- RECT rv;
- GetClientRect(hWND, &rv);
-
- Frustum->SetAspect((float)(rv.right - rv.left) / (float)(rv.bottom - rv.top));
- Frustum->SetWidth((float)(rv.right - rv.left));
- Frustum->SetHeight((float)(rv.bottom - rv.top));
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(Config->fFrustumFieldOfView, Frustum->GetAspect(), Config->fFrustumZNear, Config->fFrustumZFar);
- glViewport(rv.left, rv.top, rv.right - rv.left, rv.bottom - rv.top);
- glMatrixMode(GL_MODELVIEW);
-
- MakeNotCurrent();
- }
-
- void CEngine::Paint()
- {
- if(World == NULL)
- return;
-
- MakeCurrent();
-
- StartScene();
-
- SetCamera();
- DrawScene();
-
- Start2D();
- DrawInfo();
- End2D();
-
- EndScene();
-
- MakeNotCurrent();
- }
-
- void CEngine::LoadTextures()
- {
- String *sWADString;
-
- if(World->GetWADString(&sWADString) == false)
- {
- txtConsole->Print("WAD string not found.\n", Color::Red);
- return;
- }
-
- MakeCurrent();
- TextureManager->LoadTextures(sWADString);
- MakeNotCurrent();
- }
-
- void CEngine::UpdateTextureFilter()
- {
- if(TextureManager == NULL)
- return;
-
- MakeCurrent();
- TextureManager->UpdateTextureFilter();
- MakeNotCurrent();
- }
-
- void CEngine::DestroyTextures()
- {
- if(TextureManager == NULL)
- return;
-
- MakeCurrent();
- TextureManager->DestroyTextures();
- MakeNotCurrent();
- }
-
- void CEngine::PreRenderLoop()
- {
- Camera->InitializePerformanceCounter();
- }
-
- void CEngine::EnterRenderLoop()
- {
- bRender = true;
- PreRenderLoop();
-
- do
- {
- Application::DoEvents();
-
- if(System::Windows::Forms::Form::ActiveForm == NULL)
- {
- System::Threading::Thread::Sleep(100);
- continue;
- }
-
- MakeCurrent();
-
- StartScene();
-
- MoveCamera();
- SetCamera();
- CullScene();
- DrawScene();
-
- Start2D();
- DrawInfo();
- End2D();
-
- EndScene();
-
- MakeNotCurrent();
- }
- while(bRender == true);
- }
-
- void CEngine::ExitRenderLoop()
- {
- bRender = false;
- }
-
- void CEngine::SetWorld(CWorld *World, CTextureManager *TextureManager)
- {
- World->UpdateBrushCount();
-
- txtConsole->Print(String::Concat(World->GetBrushCount().ToString(), S" brushes loaded.\n"), Color::Green);
-
- this->World = World;
- this->HighlightObject = NULL;
- this->PointFile = NULL;
-
- DestroyTextures();
-
- this->TextureManager = TextureManager;
-
- LoadTextures();
-
- World->UpdateColors();
-
- txtConsole->Print("Calculating texture coordinates.\n", Color::Gray);
-
- World->UpdateTexCoords(TextureManager);
-
- txtConsole->Print("Calculating bounding boxes.\n", Color::Gray);
-
- World->UpdateBoundingBoxes();
-
- this->Camera->Reset();
-
- bMousePressed = false;
- bW = false;
- bA = false;
- bS = false;
- bD = false;
- bShift = false;
- bUp = false;
- bDown = false;
- bRight = false;
- bLeft = false;
- }
-
- CTextureManager *CEngine::GetTextureManager()
- {
- return this->TextureManager;
- }
-
- void CEngine::SetHighlightObject(CWorldObject *HighlightObject)
- {
- this->HighlightObject = HighlightObject;
- }
-
- void CEngine::SetPointFile(CPointFile *PointFile)
- {
- this->PointFile = PointFile;
- }
-
- void CEngine::SetMousePosition(int X, int Y)
- {
- vMouseNew.X = X;
- vMouseNew.Y = Y;
- }
-
- void CEngine::SetMousePressed(bool bMousePressed)
- {
- this->bMousePressed = bMousePressed;
- }
-
- void CEngine::SetKeyPressed(System::Windows::Forms::Keys Key, bool bKeyPressed)
- {
- switch(Key)
- {
- case System::Windows::Forms::Keys::W:
- bW = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::A:
- bA = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::S:
- bS = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::D:
- bD = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::Up:
- bUp = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::Down:
- bDown = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::Right:
- bRight = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::Left:
- bLeft = bKeyPressed;
- break;
- case System::Windows::Forms::Keys::ShiftKey:
- bShift = bKeyPressed;
- break;
- }
- }
-
- void CEngine::ClearBuffers()
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
- }
-
- void CEngine::MoveCamera()
- {
- Vertex2i vMovement;
-
- Camera->UpdateTimeElapsed();
-
- vMovement.X = vMouseOld.X - vMouseNew.X;
- vMovement.Y = vMouseOld.Y - vMouseNew.Y;
-
- if(bMousePressed)
- {
- Camera->MoveCameraAngles(Config->bInvertCamera ? -vMovement.Y : vMovement.Y, vMovement.X);
- }
-
- vMouseOld.X = vMouseNew.X;
- vMouseOld.Y = vMouseNew.Y;
-
- float fWalk = 0.0f, fStrafe = 0.0f;
-
- if(bW || bUp)
- {
- fWalk += Config->fCameraSpeed;
- }
-
- if(bS || bDown)
- {
- fWalk -= Config->fCameraSpeed;
- }
-
- if(bD || bRight)
- {
- fStrafe -= Config->fCameraSpeed;
- }
-
- if(bA || bLeft)
- {
- fStrafe += Config->fCameraSpeed;
- }
-
- if(bShift)
- {
- fWalk *= Config->fCameraBoost;
- fStrafe *= Config->fCameraBoost;
- }
-
- Camera->MoveCamera(fWalk, fStrafe);
- }
-
- void CEngine::SetCamera()
- {
- Camera->SetCamera();
- }
-
- void CEngine::CullScene()
- {
- Frustum->ResetCulled();
- Frustum->CalculateFrustum();
- World->CullWorld(Frustum);
- }
-
- void CEngine::StartScene()
- {
- ClearBuffers();
- }
-
- void CEngine::DrawScene()
- {
- switch(Config->eRenderMode)
- {
- case RenderMode::Textured:
- World->DrawWorldTextured();
- break;
- case RenderMode::Solid:
- World->DrawWorldSolid();
- break;
- case RenderMode::WireFrame:
- World->DrawWorldWireFrame();
- break;
- case RenderMode::Points:
- World->DrawWorldPoints();
- break;
- }
-
- if(Config->bOutlineScene)
- World->Outline();
-
- if(Config->bDrawSelection && this->HighlightObject != NULL)
- HighlightObject->Highlight(false);
-
- if(this->PointFile != NULL)
- PointFile->DrawPoints();
- }
-
- void CEngine::EndScene()
- {
- RenderToScreen();
- }
-
- void CEngine::Start2D()
- {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- gluOrtho2D(0.0f, Frustum->GetWidth(), 0.0f, Frustum->GetHeight());
- glScalef(1.0f, -1.0f, 1.0f);
- glTranslatef(0.0f, -Frustum->GetHeight(), 0.0f);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- //glNormal3f(0.0f, 0.0f, 1.0f);
- }
-
- void CEngine::DrawInfo()
- {
- Color3uc Color;
- Color.R = 255;
- Color.G = 0;
- Color.B = 0;
-
- RenderText(String::Concat(S"FPS: ", Camera->GetFPS().ToString("0.00")), 4, 4, Color);
- RenderText(String::Concat(S"Brushes drawn: ", (World->GetBrushCount() - Frustum->GetCulled()).ToString(), S"/", World->GetBrushCount().ToString()), 4, 16, Color);
- }
-
- void CEngine::RenderText(String *Text, int X, int Y, Color3uc Color)
- {
- void *pText = System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(Text).ToPointer();
-
- glColor3ub(Color.R, Color.G, Color.B);
- glRasterPos2i(X, Y + 8);
-
- glPushAttrib(GL_LIST_BIT);
- glListBase(iFontBase - 32);
- glCallLists(Text->Length, GL_UNSIGNED_BYTE, pText);
- glPopAttrib();
-
- glRasterPos2i(0, 0);
-
- System::Runtime::InteropServices::Marshal::FreeHGlobal((IntPtr(pText)));
- }
-
- void CEngine::End2D()
- {
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
-
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- }
-
- void CEngine::RenderToScreen()
- {
- glFlush();
- SwapBuffers(hDC);
- }
-
- bool CEngine::TestExtension(String *sExtension)
- {
- MakeCurrent();
- char *szExtension = (char *)(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(sExtension)).ToPointer();
-
- char *p = (char *)glGetString(GL_EXTENSIONS);
- char *end;
- int extNameLen;
-
- extNameLen = strlen(szExtension);
- end = p + strlen(p);
-
- while(p < end)
- {
- int n = strcspn(p, " ");
- if ((extNameLen == n) && (strncmp(szExtension, p, n) == 0))
- {
- System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr((void*)szExtension));
- MakeNotCurrent();
-
- return true;
- }
- p += (n + 1);
- }
-
- System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr((void*)szExtension));
- MakeNotCurrent();
-
- txtConsole->Print(String::Concat("Extension ", sExtension, " not supported.\n"), Color::Red);
-
- return false;
- }